<template>
  <div class="gui_table_box" ref="gui_table_box" :class="{ 'el-card': cardStyle }">
    <div class="slot_title" v-if="title || $slots.header">
      <slot name="header">
        <span>{{ title }}</span>
      </slot>
    </div>
    <div class="gui_top_box">
      <slot name="topBox"></slot>
    </div>
    <div class="gui_table_title_box">
      <slot name="tableTitle"></slot>
    </div>
    <el-table
      stripe
      :border="$attrs.border || true"
      :row-style="{ height: '30px' }"
      :cell-style="cellstyle"
      :height="tableH || 'auto'"
      v-bind="$attrs"
      v-on="$listeners"
      ref="gx_table"
      class="gx_table"
    >
      <slot></slot>
      <template v-for="(item, i) in column">
        <!-- 兼容序号，勾选等type值 -->
        <el-table-column
          :key="i"
          v-bind="{ ...{ align: 'center' }, ...item }"
          v-if="item.hasOwnProperty('type') && item.type == 'expand'"
        >
          <template slot-scope="scope">
            <slot name="expand" :row="scope.row"></slot>
          </template>
        </el-table-column>

        <el-table-column
          v-bind="{ ...{ align: 'center' }, ...item }"
          :key="i + 'type'"
          v-else-if="item.hasOwnProperty('type')"
        ></el-table-column>

        <my-column :key="i + 'custom'" :item="item" v-else>
          <template v-for="p in slotList" v-slot:[p]="{ row, $index, column }">
            <slot :name="p" :row="row" :$index="$index" :column="column"></slot>
          </template>
        </my-column>
      </template>
    </el-table>
    <el-pagination
      class="gui_pagination"
      v-show="total != 0"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      :current-page="currentPage"
      :page-sizes="pageSizeList"
      :page-size="pageSize"
      :layout="layout"
      :total="total"
    ></el-pagination>
  </div>
</template>

<script>
//三层表头目前无法支持自定义插槽渲染
import Vue from 'vue';
// 自定义内容的函数式组件
const ExSlot = {
  functional: true,
  props: {
    row: Object,
    render: Function,
    index: Number,
    column: {
      type: Object,
      default: null,
    },
  },
  render: (h, data) => {
    const params = {
      row: data.props.row,
      index: data.props.index,
    };
    if (data.props.column) params.column = data.props.column;
    return data.props.render(h, params);
  },
};
// 多级表头无限嵌套
const MyColumn = Vue.component('my-column', {
  props: {
    item: { type: Object, default: () => {} },
    emptySymbol: { type: String, default: '-' },
  },
  components: { ExSlot },
  template: `
    <el-table-column v-bind="{ ...{ align: 'center' }, ...item }">
      <template v-if="item.hasOwnProperty('children')">
        <my-column v-for="(m, n) in item.children" :item="m" :key="n">
          <template v-for='p in myColSlotList' v-slot:[p]="{ row ,$index,column}">
            <slot :name="p" :row="row" :$index="$index" :column="column"></slot>
          </template>
        </my-column>
      </template>
      <template slot-scope="scope">
        <!-- 展示自己定义内容 -->
        <slot v-if="item.hasOwnProperty('isSlot')" :name="item.prop" :row="scope.row" :$index="scope.$index" :column="item"></slot>
        <ex-slot v-else-if="item.render" :render="item.render" :row="scope.row" :index="scope.$index" :column="item" />
        <!-- 直接渲染值,封装了当为字段值为null或为空字符串时,展示空字符符号 -->
        <span v-else>
          {{  (scope.row[item.prop] !== 0 && !scope.row[item.prop]) ||
          scope.row[item.prop] === null || scope.row[item.prop] === "" || scope.row[item.prop] === "null"
          ? emptySymbol
          :scope.row[item.prop] === "kongge$"?"":scope.row[item.prop]
          }}
        </span>
      </template>
    </el-table-column>
  `,
  computed: {
    // 插槽集合 （item.children中所有isSlot对应的prop集合）
    myColSlotList() {
      const { item } = this;
      let arrList = [];
      if (item.children && item.children[0]) {
        arrMap(item.children);
      }
      function arrMap(arr) {
        arr.forEach((m) => {
          if (m.children && m.children[0]) {
            arrMap(m.children);
          } else {
            if (m.isSlot) {
              arrList.push(m.prop);
            }
          }
        });
      }

      return arrList;
    },
  },
});

export default {
  inheritAttrs: false,
  props: {
    cellstyle: {
      default: () => {
        return {
          padding: '2px',
          color: '#000',
          'border-color': '#b3b3b3',
          'font-size': '13px',
        };
      },
    },
    title: { type: String, default: '' },
    cardStyle: { type: Boolean, default: false },
    /** 分页 **/
    total: { type: [String, Number], default: 0 },
    currentPage: { type: [String, Number], default: 1 },
    pageSize: { type: [String, Number], default: 10 },
    pageSizeList: { type: Array, default: () => [10, 50, 100, 200] },
    layout: {
      type: String,
      default: 'total, sizes, prev, pager, next, jumper',
    },
    /** 表格列头数组 **/
    /**
      * 自定义列示例：
        <template v-slot:sTNM="{ row }">
          <div>{{ row.sTNM }}</div>
        </template>

        column自定义中{label: "", prop: "sTNM", isSlot: true}
    */
    column: { type: Array, default: () => [] },
    height: { type: [String, Number] },
    emptySymbol: { type: String, default: '-' },
    autoResize: { type: Boolean, default: true },
  },
  components: { MyColumn },
  computed: {
    // 插槽集合 （column中所有isSlot对应的prop集合）
    slotList() {
      const { column } = this;
      let arrList = [];
      arrMap(column);
      function arrMap(arr) {
        arr.forEach((m) => {
          if (m.children && m.children[0]) {
            arrMap(m.children);
          } else {
            if (m.isSlot) {
              arrList.push(m.prop);
            }
          }
        });
      }
      return arrList;
    },
  },
  data() {
    return {
      tableH: this.height,
      observer: null,
    };
  },
  mounted() {
    this.autoResize &&
      this.$nextTick(() => {
        this.divResizeEvent();
      });
  },
  watch: {
    total: {
      immediate: true,
      handler(newVal, oldVal) {
        if (newVal !== oldVal) {
          this.computedHeight();
        }
        const maxPage = Math.max(Math.ceil(newVal / this.pageSize), 1);
        if (this.currentPage > maxPage) {
          this.$emit('currentChange', maxPage);
        }
      },
    },
    column: {
      immediate: true,
      handler(newVal, oldVal) {
        this.$nextTick(() => {
          //表格懒加载
          this.doLayout();
        });
        if (newVal != oldVal) {
          this.computedHeight();
        }
      },
    },
  },
  beforeDestroyed() {
    // 销毁监听事件
    if (this.observer) {
      this.observer.disconnect();
      this.observer.takeRecords();
      this.observer = null;
    }
  },
  methods: {
    //监听div宽度变化改变echarts图表--echarts图表的resize
    divResizeEvent() {
      let element = document.querySelector('.stationDialogVisible');
      if (!element) {
        this.computedHeight();
        return false;
      }
      // 兼容首页弹窗的收缩拉伸、全屏
      let MutationObserver =
        window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;
      this.computedHeight();
      this.observer = new MutationObserver((mutationList) => {
        let oldStyle = {};
        for (let mutation of mutationList) {
          let recordOldValueList = mutation.oldValue.split(';');
          recordOldValueList.forEach((p) => {
            let arr = p.split(':');
            let key = arr[0].replace(/(^\s*)|(\s*$)/g, '');
            if (key) {
              oldStyle[key] = arr[1].replace(/(^\s*)|(\s*$)/g, '');
            }
          });
        }

        let height = element.style.height;

        if (height && oldStyle.height) {
          // 高度变化了
          this.computedHeight();
        }
      });
      this.observer.observe(element, {
        attributes: true,
        attributeFilter: ['style'],
        attributeOldValue: true,
      });
    },
    computedHeight() {
      if (Number(this.height)) return false;
      setTimeout(() => {
        let hei = 'auto';
        let gui_table_box = this.$refs.gui_table_box?.clientHeight;
        let slot_title = document.querySelector('.gui_slot_title')?.clientHeight ?? 0;
        let table_title_box = document.querySelector('.gui_table_title_box')?.clientHeight ?? 0;
        let top_box = document.querySelector('.gui_top_box')?.clientHeight ?? 0;
        let pagination = document.querySelector('.gui_pagination')?.clientHeight ?? 0;

        hei = gui_table_box - slot_title - top_box - table_title_box - pagination - 10;
        this.tableH = hei;
      }, 10);
    },
    // 改变每页条数事件
    handleSizeChange(val) {
      this.$emit('sizeChange', val);
    },
    // 改变当前页码
    handleCurrentChange(val) {
      this.$emit('currentChange', val);
    },
    doLayout() {
      //表格懒加载
      this.$refs.gx_table && this.$refs.gx_table.doLayout();
    },
  },
};
</script>

<style lang="less" rel="stylesheet/less" scoped>
.el-card {
  border: none;
  padding: 10px 20px;
}
.gui_table_box {
  height: 100%;
  width: 100%;
  .gui_slot_title {
    border-bottom: 1px solid #eee;
    padding-bottom: 16px;
    margin-bottom: 16px;
    font-size: 18px;
    line-height: 21px;
    font-weight: bold;
    &::before {
      content: '';
      display: inline-block;
      vertical-align: middle;
      width: 4px;
      background: #3977f0;
      height: 22px;
      margin-right: 6px;
      margin-left: 1px;
    }
  }
  .gui_top_box {
    display: flex;
    align-items: center;
    justify-content: space-between;
    position: relative;
    .search_box {
      margin-bottom: 20px;
      p {
        display: inline-block;
        vertical-align: middle;
        .el-select,
        .el-input {
          width: 200px !important;
          margin-right: 24px;
        }
      }
    }
  }
  /deep/ .el-table {
    .el-tooltip {
      visibility: visible;
    }
  }
  .gx_table {
    /deep/ .el-table__header th {
      text-align: center;
      padding: 0 !important;

      background: #f5f5f5;
      height: 30px;
      color: #000;
      padding: 0;
      font-size: 12px;
      border-color: #b3b3b3;
    }
    /deep/ .el-table__header th .cell {
      padding: 0 !important;
    }
    /deep/ .el-table__row td > div {
      // display: inline-flex;
      // align-items: center;
      width: 100%;
      height: 100%;
      text-align: center;
    }
    /deep/ .el-table__row td div.el-tooltip {
      display: block;
    }
  }
  /deep/ .el-table__header th .cell > .caret-wrapper {
    display: none;
  }
  /deep/.el-table__empty-block {
    border-right: 1px solid #ebeef5;
  }
  .gui_pagination {
    padding: 16px 0px 24px;
  }
}
.card_box {
  padding: 20px;
}
.el-table {
  border-color: #b3b3b3 !important;
  color: rgba(0, 0, 0, 1);

  th {
    background: rgba(0, 0, 0, 0);
  }
  .el-table__empty-block {
    box-sizing: border-box;
    background: #011431;
    border-bottom: 1px solid #b3b3b3 !important;
    border-right: 1px solid #b3b3b3 !important;
  }
  /deep/ .el-table__body-wrapper {
    // 层级过高会导致fixed被遮住
    // z-index: 10;
    // 滚动条的宽度
    &::-webkit-scrollbar {
      width: 8px;
      height: 12px;
      border-radius: 12px;
    }
  }
}
.moreRain_box {
  .gui_table_box .gx_table {
    /deep/.el-table__header th .cell {
      white-space: nowrap !important;
    }
  }
}
</style>
